// Copyright 2013 wetalk authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package post

import (
	"fmt"
	//	"reflect"
	"regexp"

	"github.com/astaxie/beego"
	//	"github.com/astaxie/beego/orm"

	"git.oschina.net/lijinchao2007/wetalk/modules/models"
	"git.oschina.net/lijinchao2007/wetalk/modules/mongo"
	"git.oschina.net/lijinchao2007/wetalk/modules/utils"
	"git.oschina.net/lijinchao2007/wetalk/setting"
	//	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func ListCommentsOfPost(postmodel *models.Post, comments *[]*models.Comment) (int64, error) {

	if err := mongo.GetCollection(models.CommentModelName).Find(bson.M{"postid": postmodel.Id_}).All(comments); err != nil {
		beego.Error(err)
		return 0, err
	}
	for _, comment := range *comments {
		author := models.User{Id_: comment.UserId}
		author.Read()
		comment.User = &author
		if comment.PostIdd != nil {
			tt := models.Post{}
			mongo.GetDB().FindRef(comment.PostIdd).One(&tt)
			//			beego.Info("ListCommentsOfPost", comment.PostIdd, tt)
		}
	}
	//	beego.Info("ListCommentsOfPost", postmodel.Id_, *comments)

	//	job := &mgo.MapReduce{
	//		Map:    "function() { emit(this.postid, this.message) }",
	//		Reduce: "function(key, values) { var ret={postid:key,messages:values};    return ret; }",
	//	}
	//	var result []struct {
	//		PostId bson.ObjectId `_id`
	//		Value  map[string]interface{}
	//	}
	//	if info, err := mongo.GetCollection(models.CommentModelName).Find(bson.M{"postid": postmodel.Id_}).MapReduce(job, &result); err != nil {
	//		beego.Error(err)

	//	} else {
	//		beego.Info("ListCommentsOfPost Map ", info)
	//		beego.Info("ListCommentsOfPost Map ", result[0].PostId.Hex())
	//		beego.Info("ListCommentsOfPost Map ", result[0].Value)
	//	}

	//	result := []models.Comment{}
	//	pipe := mongo.GetCollection(models.CommentModelName).Pipe([]bson.M{{"$match": bson.M{"message": "ccccccc"}}})
	//	iter := pipe.Iter()
	//	iter.All(&result)
	//	//	for iter.Next(&result) {
	//	//		beego.Info("ListCommentsOfPost ", result)
	//	//	}
	//	if err := iter.Close(); err != nil {
	//		beego.Info("ListCommentsOfPost ", err)
	//		//		return err
	//	}
	//	result := map[string]interface{}{"aa": "bb"}
	//	beego.Info("ListCommentsOfPost ", result)
	//	mongo.GetDB().Run(bson.D{{"distinct", "comment"}, {"key", "postid"}}, &result)

	//	beego.Info("ListCommentsOfPost ", result)

	return int64(len(*comments)), nil
}

func ListPostsOfCategory(cat *models.Category, posts *[]models.Post) (int64, error) {
	err := models.Posts().Find(bson.M{"categoryid": cat.Id_}).Sort("-updated").All(posts)
	return int64(len(*posts)), err
}

func ListPostsOfTopic(topic *models.Topic, posts *[]models.Post) (int64, error) {
	err := models.Posts().Find(bson.M{"topicid": topic.Id_}).Sort("-updated").All(posts)
	return int64(len(*posts)), err
}

var mentionRegexp = regexp.MustCompile(`\B@([\d\w-_]*)`)

func FilterMentions(user *models.User, content string) {
	matches := mentionRegexp.FindAllStringSubmatch(content, -1)
	mentions := make([]string, 0, len(matches))
	for _, m := range matches {
		if len(m) > 1 {
			mentions = append(mentions, m[1])
		}
	}
	// var users []*User
	// num, err := Users().Filter("UserName__in", mentions).Filter("Follow__User", user.Id).All(&users)
	// if err == nil && num > 0 {
	// TODO mention email to user
	// }
}

func PostBrowsersAdd(uid int, ip string, post *models.Post) {
	var key string
	if uid == 0 {
		key = ip
	} else {
		key = utils.ToStr(uid)
	}
	key = fmt.Sprintf("PCA.%s.%s", post.Id_.Hex(), key)
	//	beego.Info("PostCounterAdd key ", key)
	if setting.Cache.Get(key) != nil {
		//		beego.Info("PostCounterAdd key added")
		return
	}
	err := post.AddBrowser()
	if err != nil {
		beego.Error("PostCounterAdd ", err)
	}
	setting.Cache.Put(key, true, 60)
}

func PostReplysCount(post *models.Post) {
	cnt, err := post.CommentsCount()
	if err == nil {
		post.Replys = int(cnt)
		err = post.Update("Replys")
	}
	if err != nil {
		beego.Error("PostReplysCount ", err)
	}
}

func ListPost(posts *[]models.Post) (int64, error) {
	if err := mongo.GetCollection(models.PostModelName).Find(nil).Sort("-Created").Limit(25).All(posts); err != nil {
		beego.Error(err)
		return -1, err
	}
	for index, _ := range *posts {
		postptr := &(*posts)[index]
		LoadPostRel(postptr)
		//		fmt.Printf("%v\n", reflect.TypeOf(postptr))
		//		beego.Info(reflect.ValueOf(*posts).Pointer())
		//		beego.Info(reflect.ValueOf(postptr).Pointer())
		//		fmt.Printf("%v\n", *postptr)
		//		fmt.Printf("%v\n", &postptr)
		//		beego.Info("LoadPostRel", postptr)
		//		beego.Info("LoadPostRel", *postptr)
	}
	return 0, nil
}

func LoadPostRel(post *models.Post) {

	author := models.User{Id_: post.UserId}
	author.Read()
	post.User = &author
	//	beego.Info("LoadPostRel", *post.User)
	author = models.User{Id_: post.LastReplyId}
	author.Read()
	post.LastReply = &author

	author = models.User{Id_: post.LastAuthorId}
	author.Read()
	post.LastAuthor = &author

	topic := models.Topic{Id_: post.TopicId}
	topic.Read()
	post.Topic = &topic

	category := models.Category{Id_: post.CategoryId}
	category.Read()
	post.Category = &category
}
